/**
 * @author : River
 * @version : 1.1
 * @time : 2004.04.10
 */
package com.j3.sql;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.List;

import org.apache.log4j.Logger;

import com.j3.db.ConnectionManager;
import com.j3.db.DataSourceUnRegisterException;
import com.j3.db.Db;

public class BatchFunc {
	private static final Logger LOGGER = Logger.getLogger(BatchFunc.class);

	public BatchFunc() {
	}

	/**
	 * @param sql String
	 * @param args String[]
	 * @param autoCommit boolean
	 * @throws SQLException
	 * @return boolean
	 */
	public boolean doBatch(String sql, String[] args, boolean autoCommit) throws SQLException, DataSourceUnRegisterException {
		Connection conn = ConnectionManager.getConn();
		try {
			if (!autoCommit) {
				return doBatch(conn, sql, args);
			}
			PreparedStatement pstmt = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				pstmt.setString(1, args[i]);
				pstmt.addBatch();
			}
			pstmt.executeBatch();
			pstmt.close();
		}finally {
			ConnectionManager.close(conn);
		}
		return true;
	}

	/**
	 * @param conn Connection
	 * @param sqlstr String
	 * @param vector Vector
	 * @throws SQLException
	 */
	public boolean doBatch(Connection conn, String sqlstr, String[] args) throws SQLException {
		try {
			if (args == null) {
				return true;
			}
			conn.setAutoCommit(false);
			boolean allok = true;
			PreparedStatement ps = conn.prepareStatement(sqlstr);
			for (int i = 0; i < args.length; i++) {
				ps.setString(1, args[i]);
				int ok = ps.executeUpdate();
				if (ok <= 0) {
					allok = false;
					break;
				}
			}
			if (allok) {
				conn.commit();
			} else {
				conn.rollback();
			}
			ps.close();
			return allok;
		} catch (SQLException e) {
			LOGGER.error("Exception in BatchFunc,method doBatch(). sql=" + sqlstr, e);
			throw e;
		}
	}

	private boolean doBatch(Connection conn, List<String> list) throws SQLException {
		boolean allok = true;
		try {
			conn.setAutoCommit(false);
			Statement stmt = conn.createStatement();
			for (int i = 0; i < list.size(); i++) {
				stmt.addBatch(list.get(i));
			}
			int[] resultInts = stmt.executeBatch();
			for (int i = 0; i < resultInts.length; i++) {
				if (resultInts[i] < 0) {
					LOGGER.error(list.get(i));
					conn.rollback();
					allok = false;
					break;
				}
			}
			conn.commit();
			stmt.close();
		} catch (SQLException e) {
			LOGGER.fatal("Exception in BatchFunc,method doBatch().", e);
			throw e;
		}
		return allok;
	}

	public boolean doBatch(String dataSourceName, List<String> list) throws SQLException, DataSourceUnRegisterException {
		Connection conn = ConnectionManager.getConn(dataSourceName);
		try {
			return doBatch(conn, list);
		}finally {
			ConnectionManager.close(conn);
		}
	}

	public boolean doBatch(Db db, List<String> list) throws SQLException, DataSourceUnRegisterException {
		Connection conn = ConnectionManager.getConn(db);
		try {
			return doBatch(conn, list);
		}finally {
			ConnectionManager.close(conn);
		}
	}

	/**
	 * @param sqlstr String
	 * @param vector Vector
	 * @return boolean
	 */
	public boolean doBatch(List<String> list) throws SQLException, DataSourceUnRegisterException {
		String dataSourceName = ConnectionManager.getDefaultDataSource();
		return doBatch(dataSourceName, list);
	}


	public boolean doBatch(String[] querys) throws SQLException, DataSourceUnRegisterException {
		return doBatch(Arrays.asList(querys));
	}

}
